from typing import Optional, Union

import pandas as pd

from snowflake.snowpark import DataFrame as SnowflakeDataFrame
from snowflake.snowpark.session import Session
from typing_extensions import Protocol

#: pylint: disable=invalid-name


ConfigValue = Union[str, bool, float, int]


class Config(Protocol):
    """Model configuration"""

    #: pylint: disable=too-few-public-methods

    @staticmethod
    def get(key: str, default: Optional[ConfigValue] = None) -> ConfigValue:
        """Get the value of a keky in the config dictionary"""


class This(Protocol):
    """Reference to this model's database table"""

    database: str
    schema: str
    identifier: str


class Dbt(Protocol):
    """DBT interface"""

    config: Config
    this: This
    is_incremental: bool

    def ref(self) -> SnowflakeDataFrame:
        """References to other models"""

    def source(self) -> SnowflakeDataFrame:
        """References to sources"""

def model(dbt: Dbt, session: Session) -> pd.DataFrame:
    """Build the Python model

    Parameters
    ----------
    dbt : Dbt
        DBT object with configuration and references
    session : Session
        Snowpark session

    Returns
    -------
    pd.DataFrame
        pandas DataFrame
    """

    #: pylint: disable=unused-argument

    df = dbt.ref("another_model").to_pandas()

    return df